// Created: Dec 14, 2014
//
// Author: wjinwen.1988@gmail.com

#include "chi/net/event_loop_thread.h"
#include "chi/net/event_loop.h"

namespace chi {
namespace net {

EventLoopThread::EventLoopThread(const ThreadInitCallback& cb) 
  : loop_(nullptr),
    exiting_(false),
    thread_(std::bind(&EventLoopThread::ThreadRuntime, this)),
    mutex_(),
    cond_(mutex_),
    callback_(cb) {
}

EventLoopThread::~EventLoopThread() {
}

EventLoop* EventLoopThread::StartLoop() {
  assert(!thread_.started());
  thread_.Start();

  {
    MutexLockGuard lock(mutex_);
    while (loop_ == nullptr) {
      cond_.Wait();
    }
  }
  return loop_;
}

void EventLoopThread::StopLoop() {
  exiting_ = true;
  loop_->Quit();
  thread_.Join();
}

void EventLoopThread::ThreadRuntime() {
  EventLoop loop;
  
  if (callback_) {
    callback_(&loop);
  }

  { 
    MutexLockGuard lock(mutex_);
    loop_ = &loop;
    cond_.Notify();
  }

  loop.Loop();
}

}  
}
